﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day05
{
    class Program
    {
        //委托
        static void Main1(string[] args)
        {
            float[] arr = { 1.0f, 3.0f, 2.0f };
            float[] myArr = { 7.0f, 1.0f, 3.0f, 2.0f };
            string[] arr2 = { "1", "3", "2" };
            //BubbleSort<float>(arr);
            //BubbleSort(arr);
            //4.通过方法创建委托对象（绑定方法）
            CompareHandler<float> handler = new CompareHandler<float>(Condition1);//【委托包装方法】
            BubbleSort(arr,handler);//本质传递的是Condition1方法
            MyBubbleSort(myArr, handler);
        }
        static void Main(string[] args)
        {
            //泛型委托
            //Action 没有返回值的委托
            //例如：Action --> void Fun1()
            //      Action<int,string> --> void Fun1(int a,string b)
            //Func   具有返回值的委托
            //例如：Func<int> --> int Fun1()
            //    Func<int,string,bool>--> bool Fun1(int a, string b)
            //    Func<char,bool,int>--> int Fun1(char a, bool b)

            float[] arr = { 1.0f, 3.0f, 2.0f };
            float[] myArr = { 7.0f, 1.0f, 3.0f, 2.0f };
            float[] myArr2 = { 7.0f, 1.0f, 3.0f, 2.0f };
            float[] myArr3 = { 7.0f, 1.0f, 3.0f,7.0f, 2.0f, 5.0f};
            string[] arr2 = { "1", "3", "2" };
            //4.通过方法创建委托对象（绑定方法）

            //*1* 原始版本——结构清晰，书写麻烦
            //CompareHandler<float> handler = new CompareHandler<float>(Condition1);//【委托包装方法】简化为下一行代码
            //BubbleSort(arr, handler);//本质传递的是Condition1方法

            //*2* 进阶版本——直接赋值方法-->匿名方法-->Lambda表达式（=>goes to）
            //1).声明委托 直接赋值方法
            //CompareHandler<float> handler = Condition1;//【委托包装方法】再简化到下一行代码
            //BubbleSort(arr, Condition1);//本质传递的是Condition1方法

            //2).匿名方法
            //CompareHandler<float> handler = delegate (float a, float b) { return a > b; };//简化为下一行代码

            //3).Lambda表达式 => goes to
            //CompareHandler<float> handler = (a, b) { return a > b; };//再简化为下一行代码
            CompareHandler<float> handler =  (a, b) => a > b;
            MyBubbleSort(myArr, handler);

            //*3* 终极版本——化繁为简
            BubbleSort(arr, (a, b) => a < b);//本质传递的是Condition1方法
            BubbleSortFinal(myArr2, (a, b) => a > b);//终极版本
            MyBubbleSortFinal(myArr3,(a, b) => a > b);
        }
        //冒泡排序
        //变化点：  类型  逻辑
        //应对变化：泛型  委托
        //（1创建接口 2声明接口类型引用 3调用接口方法 【4创建实现类】 5创建实现类对象）
        //委托省略了第4步
        //2.声明委托变量
        //局限冒泡排序
        private static void Sort(int[] array)
        {//2 8 6 1
         //两两比较 满足条件的放到前面

            for (int j = 0; j < array.Length - 1; j++)
            {
                for (int i = j + 1; i < array.Length; i++)
                {
                    //发现更大的交换
                    if (array[j] < array[i])
                    {
                        //交换
                        int temp = array[j];
                        array[j] = array[i];
                        array[i] = temp;
                    }
                }
            }
            ////取出第一个数据 与后面进行比较
            //for (int i = 1; i < array.Length; i++)
            //{
            //    //发现更大的交换
            //    if (array[0] < array[i])
            //    {
            //        //交换
            //    }
            //}
            ////取出第二个数据 与后面进行比较
            //for (int i = 2; i < array.Length; i++)
            //{
            //    //发现更大的交换
            //    if (array[1] < array[i])
            //    {
            //        //交换
            //    }
            //}
            //……

        }
        //老师的冒泡排序-委托
        private static void BubbleSort<T>(T[] array, CompareHandler<T> handler)
        {//2 8 6 1
         //两两比较 满足条件的放到前面

            for (int j = 0; j < array.Length - 1; j++)
            {
                for (int i = j + 1; i < array.Length; i++)
                {
                    //发现更大的交换
                    //if (array[j] < array[i])
                    //3.调用委托 间接执行方法
                    if (handler(array[j], array[i]))
                    {
                        //交换
                        T temp = array[j];
                        array[j] = array[i];
                        array[i] = temp;
                    }
                }
            }
        }
        //老师的冒泡排序-委托终极版
        private static void BubbleSortFinal<T>(T[] array, Func<T,T,bool> handler)
        {//2 8 6 1
         //两两比较 满足条件的放到前面

            for (int j = 0; j < array.Length - 1; j++)
            {
                for (int i = j + 1; i < array.Length; i++)
                {
                    //发现更大的交换
                    //if (array[j] < array[i])
                    //3.调用委托 间接执行方法
                    if (handler(array[j], array[i]))
                    {
                        //交换
                        T temp = array[j];
                        array[j] = array[i];
                        array[i] = temp;
                    }
                }
            }
        }
        //我的冒泡排序-委托非终极版
        private static void MyBubbleSort<T>(T[] array, CompareHandler<T> handler)//2.声明委托变量
        {
            for (int i = 0; i < array.Length; i++)
            {
                for (int j = 0; j < array.Length - 1 - i; j++)
                {
                    //发现更大的交换
                    //if (array[j] < array[i])
                    //3.调用委托 间接执行方法
                    if (handler(array[j], array[j+1]))
                    {
                        //交换
                        T temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }
        //我的冒泡排序-委托终极版
        private static void MyBubbleSortFinal<T>(T[] array, Func<T,T,bool> handler)//2.声明委托变量
        {
            for (int i = 0; i < array.Length; i++)
            {
                for (int j = 0; j < array.Length - 1 - i; j++)
                {
                    //发现更大的交换
                    //if (array[j] < array[i])
                    //3.调用委托 间接执行方法
                    if (handler(array[j], array[j + 1]))
                    {
                        //交换
                        T temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }
        //回调函数：通过函数指针【方法地址】调用的函数。
        //通俗讲，自己做的方法，自己不用，专门交给别人使用。调用者自己做了一个排序的方法，但自己不用，而是用委托包装后传给被调用者。
        //委托方法，即排序条件
        private static bool Condition1(float a, float b)
        {
            return a < b;
        }
    }
}
